gboolean have_server_repeat;
uint32_t server_repeat_rate;
uint32_t server_repeat_delay;
+
+ struct wl_callback *repeat_callback;
guint32 repeat_timer;
guint32 repeat_key;
guint32 repeat_count;
GdkDeviceManagerClass parent_class;
};
+static void deliver_key_event (GdkWaylandDeviceData *device,
+ uint32_t time_,
+ uint32_t key,
+ uint32_t state);
GType gdk_wayland_device_manager_get_type (void);
G_DEFINE_TYPE (GdkWaylandDeviceManager,
g_source_remove (device->repeat_timer);
device->repeat_timer = 0;
}
+
+ g_clear_pointer (&device->repeat_callback, wl_callback_destroy);
}
static void
g_source_set_name_by_id (device->repeat_timer, "[gtk+] keyboard_repeat");
}
+static void
+sync_after_repeat_callback (void *data,
+ struct wl_callback *callback,
+ uint32_t time)
+{
+ GdkWaylandDeviceData *device = data;
+
+ g_clear_pointer (&device->repeat_callback, wl_callback_destroy);
+
+ deliver_key_event (device, device->time, device->repeat_key, 1);
+}
+
+static const struct wl_callback_listener sync_after_repeat_callback_listener = {
+ sync_after_repeat_callback
+};
+
static gboolean
keyboard_repeat (gpointer data)
{
GdkWaylandDeviceData *device = data;
+ GdkWaylandDisplay *display = GDK_WAYLAND_DISPLAY (device->display);
- deliver_key_event (device, device->time, device->repeat_key, 1);
+ /* Ping the server and wait for the timeout. We won't process
+ * key repeat until it responds, since a hung server could lead
+ * to a delayed key release event. We don't want to generate
+ * repeat events long after the user released the key, just because
+ * the server is tardy in telling us the user released the key.
+ */
+ device->repeat_callback = wl_display_sync (display->wl_display);
+
+ wl_callback_add_listener (device->repeat_callback,
+ &sync_after_repeat_callback_listener,
+ device);
return G_SOURCE_REMOVE;
}